/**
 * Created by Administrator on 2017/1/15.
 */

var config = require('./config');

var MJ = require('../MJ/MJ');
var MJRoom = require('../MJ/room').MJRoom;

var Const = require('./const');
var SubCode = require('../subCode');

exports.XQMJRoom = MJRoom.extend({

    init: function (rid, creator, msg) {
        this._super(rid, creator, msg);

        this.specialMode = this.getOption("specialMode");
        this._lastCard = 0;
        this._curTaskFrom = 0;
        this.setSaveReplay(true);
    },

    /******************************************************************
     * 重载的接口
     ******************************************************************/

    getRoomConfig: function () {
        var cfg = this._super();
        return cfg;
    },

    //获取房间信息
    getInfo: function () {
        var info = this._super();

        info.rounds = this.getRound();
        info.curRounds = this.getCurRound();

        return info;
    },

    //获取本轮房间信息
    getRoundInfo: function () {
        var info = this._super();
        info.curRounds = this.getCurRound();
        return info;
    },

    //重新连接信息
    getReconnectInfo: function (rePlayer) {
        var info = this._super(rePlayer);
        return info;
    },

    //开始新一轮之前的事件
    onBeforeStartNewRound: function () {
        this._super();
    },

    //开始新一轮之后的事件
    onAfterStartNewRound: function () {
        this._super();
        this.preStartPlay();
    },

    //准备开始游戏
    preStartPlay: function () {
        this.initPlayersHandCards();  //初始化玩家手牌
        this.showLastCard();        //显示牌堆中的最后一张牌
        this.startPlay();
    },

    //显示牌堆中的最后一张牌
    showLastCard: function () {
        this._lastCard = this._publicCards.lookLastCard();
        this.broadcastReplay("onLookLastCard", {
            lastCard: this._lastCard
        });
    },

    //开始游戏
    startPlay: function () {
        this._sendHangupTask(this._startPlay);//发送挂起任务
    },

    //开始游戏
    _startPlay: function () {
        this._changeCurPlay(this.getDealerIndex());//设置庄家的位置发牌
        this._doCheckNewCardHangupTask();
    },

    onBeforePlayCard: function (player, msg, card) {
        var code = this._super(player, msg, card);
        if (code) {
            return code;
        }
    },

    /**
     * 摸牌前处理
     */
    onBeforeNewCard: function () {
        var player = this.getCurPlayer();
        var huPattern = player.checkHu();
        if (huPattern == Const.Pattern.ZHAGANG) {
            var rules = [];//记录加分玩法
            if (player.isBaoTing()) {
                rules.push(Const.ScoreRule.BT);
            }
            var card = player.getLastCard() || player.getInitLastCard();
            this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), huPattern, rules);
        }
    },

    //检查摸牌后玩家的挂起任务
    checkNewCardHangupTask: function () {
        var player = this.getCurPlayer();

        var huPattern = player.checkHu();//获取胡牌的牌型
        if (huPattern && huPattern != Const.Pattern.NONE) {//是能胡的牌型
            var rules = [];//记录加分玩法
            if (player.isBaoTing()) {
                rules.push(Const.ScoreRule.BT);
            }
            if (this.getCurGang()) {
                rules.push(Const.ScoreRule.GSH);
            }
            if (huPattern == Const.Pattern.ZHAGANG) {
                var card = player.getLastCard() || player.getInitLastCard();
                this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), huPattern, rules);
            } else {
                var lastCard = player.getLastCard();
                var lastCardPoint = MJ.getPoint(lastCard);
                var lastCardColor = MJ.getColor(lastCard);
                if (lastCardColor != MJ.Color.ZI && lastCardPoint >= 4 && huPattern == Const.Pattern.NORMAL) {
                    //自摸
                    var card = player.getLastCard() || player.getInitLastCard();
                    this._hangupTask.addHuTask(player.getIndex(), card, player.getIndex(), huPattern, rules);
                }
                // if (player.isBaoTing()) {
                //     this._hangupTask.submitTask(player.getIndex(), MJ.Task.HU);
                // }
            }
        }
        var gangArray = player.checkGang();
        if (gangArray.length > 0) {
            this._hangupTask.addGangTask(player.getIndex(), gangArray);
        }
    },

    //检查出牌后其它玩家的挂起任务
    checkPlayCardHangupTask: function (card) {
        this._checkPlayCardHangupTask(card);
    },

    /***
     * 检查出牌后其它玩家的挂起任务
     */
    _checkPlayCardHangupTask: function (card) {
        var curPlay = this.getCurPlay();//当前玩家的座次
        this._curTaskFrom = 0;

        this.enumPlayers(function (eIndex, ePlayer) {//枚举所有玩家
            if (eIndex != curPlay) { //如果不是当前玩家
                if (ePlayer.checkPengWithCard(card)) {
                    this._hangupTask.addPengTask(eIndex, card, curPlay);
                }
                if (ePlayer.checkGangWithCard(card)) {
                    this._hangupTask.addGangTask(eIndex, [{
                        card: card,
                        from: curPlay,
                        gang: MJ.Gang.DIAN
                    }]);
                }
            }
        }.bind(this));
    },

    /**
     * 检查当前玩家的挂起任务
     */
    checkCurPlayHangupTask: function () {
        var player = this.getCurPlayer();
        var gangArray = player.checkGang();

        if (gangArray.length > 0) {
            this._hangupTask.addGangTask(player.getIndex(), [{
                card: gangArray[0].card,
                from: player.getIndex(),
                gang: gangArray[0].gang,
                overdue: gangArray[0].overdue
            }]);
        }
        this.onAfterNewCard();
    },

    //检查杠牌后挂起事件
    checkGangHangupTask: function (playerIndex, gangInfo) {
        var card = gangInfo.card;//杠的牌

        var QGArr = [];
        this.enumPlayers(function (eIndex, ePlayer) {//枚举每个玩家
            if (eIndex != playerIndex) {//不是当前玩家
                var huPattern = ePlayer.checkHuWithCard(card);
                if (huPattern != MJ.Pattern.NONE) {
                    var rules = [];
                    rules.push(Const.ScoreRule.QG);//抢杠

                    if (ePlayer.isBaoTing()) {
                        rules.push(Const.ScoreRule.BT);
                    }
                    var QG = new Object();
                    QG.index = eIndex;
                    QG.card = card;
                    QG.pattern = huPattern;
                    QG.rules = rules;
                    QGArr.push(QG);
                }
            }
        }.bind(this));

        QGArr.forEach(function (QG) {
            this._hangupTask.addHuTask(QG.index, QG.card, playerIndex, QG.pattern, QG.rules);
        });
    },
    //检查是否可抢杠
    checkGangTaskQG: function (task, gangInfo) {
        var card = gangInfo.card;
        var cardColor = MJ.getColor(card);
        var cardPoint = MJ.getPoint(card);
        if ((this.specialMode["QG"] == 1) && cardColor != MJ.Color.ZI && cardPoint >= 4) {
            if (gangInfo.gang == MJ.Gang.BA) {
                return true;
            }
        }
        return false;
    },
    //出牌后处理
    onAfterPlayCard: function (player, card, playInfo) {
        this._super(player, card, playInfo);
    },

    /**
     * 碰后处理
     */
    onAfterPengTask: function (player, card, pengTask) {
        this._curTaskFrom = pengTask.from;
    },

    // /**
    //  * 杠后处理
    //  */
    // onAfterGangTask: function(player, card, gangTask, gangInfo) {
    //     this._curTaskFrom = gangInfo.from;
    // },

    //检查胡牌结算
    checkHuSettlement: function () {
        return true;
    },

    //胡牌处理
    onSettlementHuTask: function (task) {
        var playerIndex = task.playerIndex;
        var pattern = task.pattern;
        var card = task.card;
        var from = task.from;
        var rules = task.rules;
        var huPlayer = this.getPlayerByIndex(playerIndex);
        var isZM = (playerIndex == from); // 是否是自摸
        var remainNum = this.getPublicCards().getLastIndex - this.getPublicCards().getIndex;//牌堆剩余的牌

        var targetsIndex = [];
        var targets = [];

        // 下面确定被扣分的玩家
        if (isZM) { // 自摸
            var hasGSH = false;
            if (remainNum <= 14 && remainNum >= 0) {
                for (var i = 0; i < rules.length; i++) {
                    if (rules[i] == Const.ItemScore.GSH) {
                        var huGangInfo = huPlayer.getLastGang();
                        if (huGangInfo.gang == MJ.Gang.AN || huGangInfo.gang == MJ.Gang.ANS) {
                            if (this._curTaskFrom != 0) {
                                var dpPlayer = this.getPlayerByIndex(this._curTaskFrom);
                                dpPlayer.setRoundScoreRule(Const.ScoreRule.DH);
                                for (var x = 0; x < 3; x++) {
                                    targetsIndex.push(dpPlayer.getIndex());
                                    targets.push(dpPlayer);
                                }
                            }
                        } else if (huGangInfo.gang == MJ.Gang.DIAN) {
                            var dpPlayer = this.getPlayerByIndex(huGangInfo.from);
                            dpPlayer.setRoundScoreRule(Const.ScoreRule.DH);
                            for (var x = 0; x < 3; x++) {
                                targetsIndex.push(dpPlayer.getIndex());
                                targets.push(dpPlayer);
                            }
                        }
                        hasGSH = true;
                        break;
                    }
                }
            }
            if (!hasGSH) {
                huPlayer.setRoundScoreRule(Const.ScoreRule.ZM);
                this.enumPlayers(function (eIndex, ePlayer) {
                    if (eIndex != playerIndex && !ePlayer.isRoundHu()) {
                        targetsIndex.push(eIndex);
                        targets.push(ePlayer);
                    }
                });
            }
        } else {
            var dpPlayer = this.getPlayerByIndex(from);
            dpPlayer.setRoundScoreRule(Const.ScoreRule.DH);
            targetsIndex.push(from);
            targets.push(dpPlayer);
        }

        var patternScore = Const.PatternScore[pattern]; //基础牌型分

        for (var i = 0; i < rules.length; ++i) {
            var rule = rules[i];
            var itemScore = Const.ItemScore[rule];      //特殊规则分
            if (rule == Const.ScoreRule.QG) {
                if (!isZM) {
                    var targetPlayer = targets[0];
                    if (targetPlayer.getIndex() == this.getCurPlay() && this.getCurGang() > 0) { // 抢杠的 被抢玩家 一定是当前玩家
                        huPlayer.setRoundScoreRule(rule);
                        huPlayer.addRoundItemScores(rule, itemScore);
                        targetPlayer.addRoundItemScores(0, -itemScore);
                        targetPlayer.unsetRoundItemScore(Const.ScoreRule.DH);
                        targetPlayer.cancelLastGangForQG(card);
                    }
                }
            } else if (rule == Const.ScoreRule.GSH) {
                huPlayer.setRoundScoreRule(rule);
                huPlayer.addRoundItemScores(rule, itemScore);
            }
        }

        var huResult = isZM ? MJ.Result.ZM : MJ.Result.DH;
        huPlayer.setRoundResult(huResult, targetsIndex, card);
        huPlayer.setRoundPattern(pattern, patternScore);
        targets.forEach(function (target) {
            target.setRoundResult(-huResult);
        });

        this.broadcastReplay("onPlayerHu", {
            playerIndex: playerIndex,
            card: card,
            from: from,
        });
    },

    //结算处理
    onSettlement: function () {
        if (this.isRoundHZ()) {//流局
            this.enumPlayers(function (eIndex, ePlayer) {
                ePlayer._stat.LaZhuangScore = 0;
                ePlayer._selectLaZhuang = 0;
            }.bind(this));
            return;
        }

        this.enumPlayers(function (eIndex, ePlayer) {
            ePlayer.settlementRules();
        });

        this.enumPlayers(function (eIndex, ePlayer) {
            ePlayer.settlementGangScore();//计算杠分
            ePlayer.settlementPatternScore();//计算牌型分
        }.bind(this));

    },

    onCurRoundFinished: function () {
        this._super();

        // 计算新的庄家
        if (this.getFirstHuPlayerIndex() == this._dealerIndex || this.isRoundHZ()) {
            this._dealerLZ++;
        } else {
            this._dealerIndex = this.getNextIndex(this._dealerIndex);
            this._dealerLZ = 1;
        }

        this.broadcastReplay("onDealerChanged", {
            dealer: this._dealerIndex,
            dealerLZ: this._dealerLZ,
            curRounds: this.getCurRound()
        });
    },

    onPlayerEnter: function (player) {
        if (player._uid == this._creator) {
            this._dealerIndex = player.getIndex();
        }
    },

    /******************************************************************
     * 消息处理
     ******************************************************************/

    /******************************************************************
     * 功能接口
     ******************************************************************/

    /**
     * 结算玩家是否听牌
     * @param player
     * @private
     */
    _settlementPlayerTing: function (player) {
        //已听牌玩家不用再检测
        if (player.isRoundTing()) {
            return;
        }

        // 对未胡牌的玩家检查是否听牌
        var tings = player.checkTing();
        var pattern = Const.Pattern.NONE;
        var patternScore = 0;
        for (var i = 0; i < tings.length; ++i) {
            var ting = tings[i];
            var score = Const.PatternScore[ting.pattern];
            if (score > patternScore) {
                pattern = ting.pattern;
                patternScore = score;
            }
        }

        player.setRoundPattern(pattern, 0);
    },

    getSettlementInfo: function () {//获取结算信息
        var info = this._super();
        info.isHZ = this.isRoundHZ(); // 是否黄庄家
        info.dealerIndex = this.getDealerIndex();
        return info;
    },

    dealHangupTaskGang: function (task) {
        logger.debug("room=%d onHangupTaskGang args=%j", this.rid(), task);
        var playerIndex = task.playerIndex;
        var player = this.getPlayerByIndex(playerIndex);

        var gangInfo = player.gangCard(task);
        if (!gangInfo) {
            return;
        }

        var card = gangInfo.card;
        var broadcastGangInfo = clone(gangInfo);
        broadcastGangInfo.playerIndex = playerIndex;

        player.setPassHu(false);
        this._changeCurPlay(playerIndex, MJ.Task.GANG);

        if (this.checkGangTaskQG(task, gangInfo)) { // 可能被抢杠
            this._hangupTask.reset();
            this.checkGangHangupTask(playerIndex, gangInfo);

            if (this._hangupTask.exist()) {
                broadcastGangInfo.existTask = true;
            }
            this.broadcastReplay("onPlayerGangCard", broadcastGangInfo);
            this.onAfterGangTask(player, card, task, gangInfo);
            this._hangupTask.source.prevTask = MJ.Task.GANG;

            if (this.checkGangNewCard(gangInfo)) {
                logger.debug("room=%d sendHangupTask in=MJ.dealHangupTaskGang checkGangTaskQG=true checkGangNewCard=true", this.rid());
                if (this.specialMode["SG"] == 1 && !player.checkZhaGang()) {
                    this._sendHangupTask(this._dealNewCard, [player]);
                } else {
                    this._sendHangupTask(this._dealLastNewCard, [player]);
                }
                this.showLastCard();
            } else {
                logger.debug("room=%d sendHangupTask in=MJ.dealHangupTaskGang checkGangTaskQG=true checkGangNewCard=false", this.rid());
                this._sendHangupTask(this._doCheckCurPlayHangupTask);
            }
        } else {
            this.broadcastReplay("onPlayerGangCard", broadcastGangInfo);
            this.onAfterGangTask(player, card, task, gangInfo);

            if (this.checkGangNewCard(gangInfo)) { // 没有则发摸牌
                if (this.specialMode["SG"] == 1 && !player.checkZhaGang()) {
                    this._sendHangupTask(this._dealNewCard, [player]);
                } else {
                    this._sendHangupTask(this._dealLastNewCard, [player]);
                }
            } else {
                this._doCheckCurPlayHangupTask();
            }
        }
        this.showLastCard();//显示最后一张牌
    },

    _dealLastNewCard: function () {
        if (this.isCurRoundFinished()) {
            return;
        }

        this.onBeforeNewCard();
        if (this.isCurRoundFinished()) {
            return;
        }

        var player = this.getCurPlayer();

        if (this._publicCards.isEmpty()) {
            this.settlementCurRound(0);
            return;
        }

        var card = this._publicCards.getLastCard();
        player.addNewCard(card);


        player.setPassHu(false);
        this._curTask = 0;
        this._sendPublicCardChanged();

        this._hangupTask.reset();
        this.checkNewCardHangupTask();

        var resp = {
            playerIndex: player.getIndex(),
            card: card,
            remain: this._publicCards.getRemainNum()
        }

        if (this._hangupTask.existUncommitted(player.getIndex())) {
            resp.existHangup = true;
        }

        this.broadcastReplay("onNewCard", resp);

        logger.debug("room=%d sendHangupTask in=MJ._dealNewCard", this.rid());
        this._sendHangupTask(this.hangupEmptyHandler);

        this.onAfterNewCard();
    },

    /******************************************************************
     * 消息处理
     ******************************************************************/

    handleEnjoy: function (player, msg, callback) {
        callback();

        var gameConfig = this.getGameConfig();
        player.costResourceSync(gameConfig.Enjoy.costs);
    },
});